
import entity
import config

class Table:
    def __init__(self, name, canvas, x, y, cfg=None):
        self.name = name
        self.p = (x,y)
        self.canvas = canvas
        if cfg is None:
            cfg = config.Configuration()
        self.cfg = cfg
        self.primary_key = None
        self.attribute_groups = []
        self.attribute_widgets = self.gw = self.gh = None
        self.group_to_widget = None
    def draw(self, test=False):
        self.canvas.setCallBack(
            str("%s:%s:%s:%s" % (self.__class__.__name__, self.name, self.p[0], self.p[1])))
        self.drawContainer()
        self.drawText()
    def barriers(self):
        result = {}
        for w in self.attribute_widgets:
            result.update(w.barriers())
        return result
    def destinationMap(self, attribute_group):
        widget = self.group_to_widget[attribute_group]
        return widget.destinationMap()
    def drawText(self):
        self.compute_geometry()
        for w in self.attribute_widgets:
            w.draw(callback=False)
    def drawContainer(self, color=None):
        self.compute_geometry()
        c = self.canvas
        cfg = self.cfg
        d = cfg.delta
        (x,y) = self.p
        w = self.gw*d
        h = self.gh*d
        if color is None:
            color = cfg.tableColor
        c.setColor(*color)
        c.addRect(x, y, w, h)
    def compute_geometry(self):
        "initialize widgits and gw, gh"
        if self.gw is not None:
            # already done: don't do it again
            return
        groups = list(self.attribute_groups)
        groups.reverse()
        widgets = []
        g2w = {}
        (x,y) = self.p
        gw = gh = 0
        d = self.cfg.delta
        # attributes going up, indented two ticks
        for g in groups:
            underline = False
            if g==self.primary_key:
                underline = True
            widget = entity.Entity(g, self.canvas, x+2*d, y, underline, center=False)
            widgets.append(widget)
            g2w[g] = widget
            gw = max(gw, widget.gw+2)
            gh = gh+widget.gh
            y = y+d*widget.gh
        # title at the top not indented
        name = self.name
        titleWidget = entity.Entity(name, self.canvas, x, y, True, center=False)
        widgets.append(titleWidget)
        gw = max(gw, titleWidget.gw)
        gh = gh + titleWidget.gh
        self.attribute_widgets = widgets
        self.group_to_widget = g2w
        self.gw = gw
        self.gh = gh
    def add_primary_key(self, attribute_group):
        pk = self.add_attribute_group(attribute_group, atFront=True)
        self.primary_key = pk
    def add_attribute_group(self, attribute_group, atFront=False):
        k = normalizeAttributes(attribute_group)
        if k in self.attribute_groups:
            raise ValueError, "multiple insert of attribute group "+repr(k)
        if atFront:
            self.attribute_groups.insert(0, k)
        else:
            self.attribute_groups.append(k)
        return k

def normalizeAttributes(atts, omit=()):
    D = {}
    for a in atts:
        if a not in omit:
            D[a] = 1
    atts = D.keys()
    L = list(atts)
    L.sort()
    return tuple(L)

def test(fontdir=".", outfile="/tmp/out.png"):
    from skimpyGimpy import canvas
    c = canvas.Canvas()
    c.addFont("propell", fontdir+"/propell.bdf")
    t = Table("MyTable", c, 0,0)
    t.add_primary_key(["primary", "key"])
    t.add_attribute_group(["first", "group"])
    t.add_attribute_group(["another", "collection"])
    t.draw()
    c.dumpToPNG(outfile)
    print "test output to", outfile

if __name__=="__main__":
    test()
